<?php
/**
 * Created by PhpStorm.
 * User: yiyu
 * Email: smalleasyu@gmail.com
 * Date: 2020-01-18 20:31:33
 * Desc:
 */

namespace app\api\controller;

use think\Controller;
use app\base\model\system\SystemConfig;
use app\base\model\user\User;
use app\core\exception\{BusinessException, ErrorCode};
use app\core\util\{JwtUtil, TokenUtil};
use app\core\log\Log4dd;

class ApiBaseController extends Controller
{
    protected $user_id = null;//当前登录用户id
    protected $currency_name = null;//当前系统使用的货币名称
    protected $account_status = null;//当前登录用户的账号状态
    protected $account_type = null;//当前登录用户的账号类型

    /**
     * Desc: 获取请求的token
     * Date: 2020/2/28 23:49
     * Author: yiyu
     * @return string
     */
    protected function getToken()
    {
        return TokenUtil::getRequestToken();
    }

    /**
     * Desc: 校验是否登录
     * Date: 2020/1/29 16:59
     * Author: yiyu
     */
    protected function checkLogin()
    {

        $token = TokenUtil::getRequestToken();

        if (empty($token)) {
            throw new BusinessException(ErrorCode::USER_LOGIN_EMPTY_TOKEN);
        }

        $payload = JwtUtil::verifyToken($token);

        if (!$payload) {
            throw new BusinessException(ErrorCode::USER_LOGIN_INVALID_TOKEN);
        }

        $this->user_id = $payload['user_id'];
        if (!$this->user_id) {
            throw new BusinessException(ErrorCode::USER_NOT_LOGIN);
        }

        if (!TokenUtil::apiHasLoginOut($this->user_id)) {
            throw new BusinessException(ErrorCode::USER_LOGIN_INVALID_TOKEN);
        }
    }

    /**
     * Desc: 校验账号状态
     * Date: 2020/1/29 16:59
     * Author: yiyu
     */
    public function checkAccountState()
    {
        if (empty($this->user_id)) {
            $module = $this->request->module();
            $controller = $this->request->controller();
            $action = $this->request->action();
            $uri = $module . '/' . $controller . '/' . $action;
            Log4dd::error('未调用校验登录方法，就校验账号类型', ['uri' => $uri, 'server' => $_SERVER]);
        }

        $this->account_status = User::getUserFieldById($this->user_id, 'account_status');

        if ($this->account_status == User::ACCOUNT_STATUS_FREEZE) {
            throw new BusinessException(ErrorCode::USER_ACCOUNT_DISABLE);
        }

        if ($this->account_status == User::ACCOUNT_STATUS_LOGOUT) {
            throw new BusinessException(ErrorCode::USER_ACCOUNT_LOGOUT);
        }
    }

    /**
     * Desc: 获取账号类型
     * Date: 2020/1/29 17:00
     * Author: yiyu
     */
    public function getAccountType()
    {
        if (empty($this->user_id)) {
            $module = $this->request->module();
            $controller = $this->request->controller();
            $action = $this->request->action();
            $uri = $module . '/' . $controller . '/' . $action;
            Log4dd::error('未调用校验登录方法，就获取账号类型', ['uri' => $uri, 'server' => $_SERVER]);
        }

        $this->account_type = User::getUserFieldById($this->user_id, 'account_type');
    }

    /**
     * Desc: 获取当前货币的名称
     * Date: 2020/1/29 10:54
     * Author: yiyu
     * @return bool|string
     */
    public function getSysCurrencyName()
    {
        $this->currency_name = SystemConfig::getSystemConfigByName('sys_currency_name', config('sys_currency_name'));
    }

    /**
     * Desc: 返回成功
     * Date: 2020/1/20 22:54
     * Author: yiyu
     * @param array $data
     * @param string $msg
     */
    public function successReturn($data = null, $msg = '')
    {
        $errorNo = ErrorCode::COMMON_SUCCESS;
        $res = [
            'code' => $errorNo,
            'msg' => empty($msg) ? ErrorCode::ERROR_MSG[ErrorCode::COMMON_SUCCESS] : $msg,
            'time' => time(),
            'data' => $data
        ];

        $this->writeLog($errorNo, $res);

        return json($res);
    }

    /**
     * Desc: 返回失败
     * Date: 2020/1/20 22:54
     * Author: yiyu
     * @param int $errorNo
     * @param string $msg
     */
    public function errorReturn($errorNo = ErrorCode::COMMON_ERROR, $msg = '')
    {
        if (!is_numeric($errorNo)) {
            $errorNo = ErrorCode::COMMON_ERROR;
        }
        $code = empty($errorNo) ? ErrorCode::COMMON_ERROR : $errorNo;
        $res = [
            'code' => $code,
            'msg' => empty($msg) ? ErrorCode::ERROR_MSG[$code] : $msg,
            'time' => time()
        ];

        $this->writeLog($code, $res);

        return json($res);
    }

    /**
     * Desc: 记录接口请求的日志
     * Date: 2020/1/20 22:54
     * Author: yiyu
     * @param $handleCode
     * @param $response
     */
    private function writeLog($handleCode, $response)
    {
        $user_id = TokenUtil::getUserIdByToken();
        $uri = $_SERVER['REQUEST_URI'];
        $startTime = $_SERVER['REQUEST_TIME_FLOAT'];
        $nowTime = microtime(true);
        $consumeTime = bcsub($nowTime, $startTime, 3) * 1000;

        $resData = [
            'Request' => $_REQUEST
        ];
        $resData['Service'] = [
            'user_agent' => $_SERVER['HTTP_USER_AGENT'],
            'method' => $_SERVER['REQUEST_METHOD'],
            'scheme' => $_SERVER['REQUEST_SCHEME'],
            'status' => $_SERVER['REDIRECT_STATUS'],
        ];
        // 只有错误请求时，才将响应包写入日志
        if ($handleCode !== ErrorCode::COMMON_SUCCESS) {
            $resData['Response'] = $response;
        }

        Log4dd::info($user_id, ['uri' => $uri, 'consumeTime' => $consumeTime, 'resData' => $resData]);
    }


}